# 1，定义一个圆形类, 半径是这个圆形的属性, 实例化一个半径为5的圆形, 一个半径为10的圆形
# 完成方法
# 计算圆形面积
# 计算圆形周长
# import math
# class Circle:
#     def __init__(self, r):
#         self.r = r
#     def area(self):
#         return math.pi * self.r ** 2
#     def perimeter(self):
#         return math.pi * 2 * self.r

# 2，定义一个用户类, 用户名和密码是这个类的属性, 实例化两个用户, 分别有不同的用户名和密码
# 登陆成功之后才创建用户对象
# 设计一个方法  修改密码

# dic1 = {'a': 123, 'b': 456}
# class User:
#     def __init__(self, username, password):
#         self.username = username
#         self.password = password
#
#     @classmethod
#     def login(cls):
#         usr = input('用户名:')
#         pwd = input('密码:')
#         if dic1.get(usr) and int(pwd) == dic1.get(usr):
#             print('登录成功')
#             return User(usr, pwd)
#         else:
#             print('登录失败')


# 3，定义一个学生类。有下面的类属性：
#     1 姓名
#     2 年龄
#     3 成绩（语文，数学，英语)[每课成绩的类型为整数]
#     类方法：
#     1 获取学生的姓名：get_name()
#     返回类型: str
#     2 获取学生的年龄：get_age()
#     返回类型: int
#     3 返回3门科目中最高的分数。get_course()
#     返回类型: int
#     写好类以后，可以定义2个同学测试下:
#     zm = Student('zhangming', 20, [69, 88, 100])
#     返回结果：
#     zhangming
#     20
#     100
# class Student:
#     def __init__(self,name,age,course):
#         self.name=name
#         self.age=age
#         self.course=course
#     def get_name(self):
#         return self.name
#     def get_age(self):
#         return self.age
#     def get_course(self):
#         return max(self.course)

# 4，定义一个列表的操作类：Listinfo
#     包括的方法:
#     1 列表元素添加: add_key(keyname)[keyname:字符串或者整数类型]
#     2 列表元素取值：get_key(num)[num:整数类型]
#     3 列表合并：update_list(list)[list:列表类型]
#     4 删除并且返回最后一个元素：del_key()
#     list_info = Listinfo([44, 222, 111, 333, 454, 'sss', '333'])
#
# class Listinfo:
#     def __init__(self,lis):
#         self.lis=lis
#     def add_key(self,keyname):
#         self.lis.append(keyname)
#     def get_key(self,num):
#         return self.lis[num]
#     def update_list(self,list):
#         self.lis.extend(list)
#     def del_key(self):
#         return self.lis.pop()

# 5，英雄自残
# 一秒打自己一次
# 掉的血是一个波动值，可以随机选择多个技能
# 有一定闪避概率，没血了会死
# import time
# import random
# class Hero:
#     def __init__(self, name, hp):
#         self.name = name
#         self.hp = hp
#     def hit(self):
#         while 1:
#             if self.hp <= 1:
#                 print('挂了')
#                 break
#             self.hp -= random.randint(0,5)  # randint为0即为闪避
#             print(f'{self.name}收到了自己的攻击，剩余血量{self.hp}')
#             time.sleep(1)

# 6，命名空间四件套
# 读程序, 标出程序的执行过程, 画出内存图解, 说明答案和为什么
# 请不要想当然, 执行之后检查结果然后再确认和自己的猜想是不是一致
# (1)
# class A:
#     Country = '中国'  # 静态变量/静态属性 存储在类的命名空间里的
#     def __init__(self, name, age, country):  # 绑定方法 存储在类的命名空间里的
#         self.name = name
#         self.age = age
#
#     def func1(self):
#         print(self)
#
# a = A('alex', 83, '印度')
# b = A('wusir', 74, '泰国')
# A.Country = '英国'
# a.Country = '日本'
# print(a.Country)  #日本  a被赋值为日本，独立在对象a的空间里
# print(b.Country)   #英国  b没有Country属性，继承得来
# print(A.Country)   #英国

# (2)


# class A:
#     Country = ['中国']  # 静态变量/静态属性 存储在类的命名空间里的
#
#     def __init__(self, name, age, country):  # 绑定方法 存储在类的命名空间里的
#         self.name = name
#         self.age = age
#
#     def func1(self):
#         print(self)
#
#
# a = A('alex', 83, '印度')
# b = A('wusir', 74, '泰国')
# a.Country[0] = '日本'
# print(a.Country)
# print(b.Country)
# print(A.Country)
#都为['日本']，Country[0]为list的引用，指向同一个内存地址,也就是同一个值
# (3)


# class A:
#     Country = '中国'  # 静态变量/静态属性 存储在类的命名空间里的
#
#     def __init__(self, name, age, country):  # 绑定方法 存储在类的命名空间里的
#         self.name = name
#         self.age = age
#         self.Country = country
#
#     def func1(self):
#         print(self)
#
#
# a = A('alex', 83, '印度')
# b = A('wusir', 74, '泰国')
# A.Country = '英国'
# a.Country = '日本'
# print(a.Country)  #日本
# print(b.Country)  #泰国
# print(A.Country)  #英国

# (4)
# class A:
#     Country = '中国'  # 静态变量/静态属性 存储在类的命名空间里的
#
#     def __init__(self, name, age, country):  # 绑定方法 存储在类的命名空间里的
#         self.name = name
#         self.age = age
#
#     def Country(self):
#         return self.Country
#
#
# a = A('alex', 83, '印度')
# b = A('wusir', 74, '泰国')
# print(a.Country)  #内存地址
# print(a.Country())  #中国
#
# 7，士兵类（Soldier）具有名字，和枪支（gun）两个属性
# 枪支属性默认为None值
# 士兵可以使用枪支开火(fire)，如果没有获得枪则提示“还没有枪”
# 枪类（Gun）有型号(model)和子弹数量（bullet_count）属性
# 枪能够发射子弹(shoot)，也可以装填子弹(add_bullet)，如果子弹数为0则不能继续发射
# class Gun:
#     def __init__(self, model, bullet_full, bullet_count):  # bullet_full:弹夹总容量,bullet_count:剩余子弹数量
#         self.model = model
#         self.bullet_count = bullet_count
#         self.bullet_full = bullet_full
#
#     def shoot(self):
#         if self.bullet_count >= 1:
#             self.bullet_count -= 1
#         else:
#             print('没子弹了')
#
#     def add_bullet(self):
#         if self.bullet_count < self.bullet_full:
#             self.bullet_count = self.bullet_full
#         else:
#             print('子弹已满，无需添加')
#
#
# class Soldier:
#     def __init__(self, name, gun=None):
#         self.name = name
#         self.gun = gun
#
#     def fire(self):
#         if self.gun:
#             print('哒哒哒')
#             self.gun.bullet_count -= 1
#         else:
#             print('还没有枪')

# 8，定义宠物类（ Pet ），猫类（Cat）和狗类（Dog）
# 宠物都有属性姓名（name）和年龄(age)
# 宠物都有吃（eat）、喝（drink）、叫（shout）的方法
# 猫除了具有宠物类的方法，还有爬树（ climbTree ）的方法
# 狗除了具有宠物类的方法，还有警戒（ police）的方法
# class Pet:
#     def __init__(self,name,age):
#         self.name=name
#         self.age=age
#     def eat(self):
#         pass
#     def drink(self):
#         pass
#     def shout(self):
#         pass
# class Cat(Pet):
#     def climb(self):
#         pass
# class Dog(Pet):
#     def police(self):
#         pass
# 9，建立一个汽车类Auto，包括轮胎个数，汽车颜色，车身重量，速度等属性
# 至少要求汽车能够加速 减速 停车
# 再定义一个小汽车类CarAuto 继承Auto 并添加空调、CD属性，并且重新实现方法覆盖加速、减速的方法
# class Auto:
#     def __init__(self,tyre_num,color,weight,speed):
#         self.tyrenum=tyre_num
#         self.color=color
#         self.weight=weight
#         self.speed=speed
#     def speedup(self):
#         self.speed+=10
#     def lowspeed(self):
#         self.speed-=10
#     def stop(self):
#         self.speed=0
# class CarAuto(Auto):
#     def __init__(self,tyre_num,color,weight,speed,aircondition,CD):
#         super().__init__(tyre_num,color,weight,speed)
#         self.aircondition=aircondition
#         self.CD=CD
#     def speedup(self):
#         self.speed+=20
#     def lowspeed(self):
#         self.speed-=20
# 10，银行卡类（BankCard）有余额（balance）属性和存款（deposit）取款（draw）的方法，
# 只要取款金额小于余额即可完成取款操作
# 信用卡类（CreditCard）继承自银行卡类，信用卡多了透支额度（CreditCard）属性，
# #如果卡中余额和透支额度的和大于取款金额即可完成取款。如果透支，显示透支金额
# class Bankcard:
#     def __init__(self, balance):
#         self.balance = balance
#
#     def deposit(self, num):
#         self.balance += num
#
#     def draw(self, num):
#         self.balance -= num
#
#
# class CreditCard(Bankcard):
#     def __init__(self, balance, CreditCard):
#         super().__init__(balance)
#         self.CreditCard = CreditCard
#
#     def draw(self, num):
#         if self.balance + self.CreditCard > num:
#             self.balance -= num
#             if self.balance>=0:
#                 print(f'剩余金额{self.balance}')
#             else:
#                 print(f'已经透支额度{abs(self.balance)}')
#         else:
#             print('额度不足')

# 选做题：
# 当买车时，有很多种品牌可以选择，比如北京现代、别克、凯迪拉克、特斯拉等，那么此时该怎样进行设计程序呢？能否根据用户输入的品牌名称来返回对应的汽车对象